using System;
using System.Collections.Generic;

//this collection of classes provide the objects used by the application to calcualate 
//the portfolio. 
namespace IPAMS.Entities
{
    // The Actions implement the IAction Interface. Every class represents a type of
    // action that is used in the project. Every action contains all the data that is
    // required for the project calculations.   
    
    /// <summary>
    /// Sell Action - provides the sell info needed to calculate the data.
    /// </summary>
    public class SellAction : IAction
    {
        #region Private Fields

        private Stock _stock;
        private DateTime _sellTime;
        private double _sellValue;
        private List<IAction> afterSellAction;
        private int _sellQuantity;
        private Currency _actionCurrency;

        #endregion

        #region C'tors

        /// <summary>
        /// Initializes a new instance of the <see cref="SellAction"/> class.
        /// </summary>
        /// <param name="sellTime">The sell time.</param>
        /// <param name="sellValue">The sell value.</param>
        /// <param name="stock">The stock.</param>
        /// <param name="quantity">The quantity.</param>
        /// <param name="actionCurrency">The action currency.</param>
        public SellAction(DateTime sellTime, double sellValue, Stock stock, int quantity, Currency actionCurrency)
        {
            _sellTime = sellTime;
            SellValue = sellValue;
            _stock = stock;
            _sellQuantity = quantity;
            _actionCurrency = actionCurrency;

            InitializeComponents();
        }

        /// <summary>
        /// Initializes the components of the sell action.
        /// </summary>
        private void InitializeComponents()
        {
            AfterSellAction = new List<IAction>();
        }

        #endregion

        #region Properties

        public List<IAction> AfterSellAction
        {
            get { return afterSellAction; }
            set { afterSellAction = value; }
        }

        public double SellValue
        {
            get { return _sellValue; }
            set { _sellValue = value; }
        }

        public DateTime ActionTime
        {
            get { return _sellTime; }
            set { _sellTime = value; }
        }

        public Stock StockInfo
        {
            get { return _stock; }
            set { _stock = value; }
        }

        public int Quantity
        {
            get { return _sellQuantity; }
            set { _sellQuantity = value; }
        }

        public Currency ActionCurrency
        {
            get { return _actionCurrency; }
            set { _actionCurrency = value; }
        }

        #endregion
        
        #region IAction Members

        public ActionTypes ActionType
        {
            get
            {
                return ActionTypes.Sell;
            }
        }

       

        #endregion
      
        #region IComparable<IAction> Members

        int IComparable<IAction>.CompareTo(IAction other)
        {
            if (other == null) return 1;
            if (ActionTime < other.ActionTime) return -1;
            if (ActionTime > other.ActionTime) return 1;
            else return 0;
        }

        #endregion
    }

    /// <summary>
    /// Buy Action - provides the buy info needed to calculate the data.
    /// </summary>
    public class BuyAction : IAction
    {
        #region Private Fields

        private Stock _stock;
        private DateTime _buyTime;
        private double _buyPrice;
        private int _buyQuantity;
        private Currency _actionCurrency;
        private List<IAction> afterBuyAction;

        #endregion

        #region C'tors

        /// <summary>
        /// Initializes a new instance of the <see cref="BuyAction"/> class.
        /// </summary>
        /// <param name="buyTime">The buy time.</param>
        /// <param name="buyPrice">The buy price.</param>
        /// <param name="stock">The stock.</param>
        /// <param name="quantity">The quantity.</param>
        /// <param name="actionCurrency">The action currency.</param>
        public BuyAction(DateTime buyTime, double buyPrice, Stock stock, int quantity, Currency actionCurrency)
        {
            _buyTime = buyTime;
            _buyPrice = buyPrice;
            _stock = stock;
            _buyQuantity = quantity;
            _actionCurrency = actionCurrency;

            InitializeComponents();
        }

        /// <summary>
        /// Initializes the components of the buy action.
        /// </summary>
        private void InitializeComponents()
        {
            AfterBuyAction = new List<IAction>();
        }

        #endregion

        #region Properties
        
        public Stock StockInfo
        {
            get { return _stock; }
            set { _stock = value; }
        }

        public List<IAction> AfterBuyAction
        {
            get { return afterBuyAction; }
            set { afterBuyAction = value; }
        }

        public double BuyPrice
        {
            get { return _buyPrice; }
            set { _buyPrice = value; }
        }

        public DateTime ActionTime
        {
            get { return _buyTime; }
            set { _buyTime = value; }
        }

        public int Quantity
        {
            get { return _buyQuantity; }
            set { _buyQuantity = value; }
        }

        public Currency ActionCurrency
        {
            get { return _actionCurrency; }
            set { _actionCurrency = value; }
        }
        #endregion

        #region IAction Members

        public ActionTypes ActionType
        {
            get
            {
                return ActionTypes.Buy;
            }
        }

        #endregion

        #region IComparable<IAction> Members
        int IComparable<IAction>.CompareTo(IAction other)
        {
            if (other == null) return 1;
            if (ActionTime < other.ActionTime) return -1;
            if (ActionTime > other.ActionTime) return 1;
            else return 0;
        }

        #endregion
    }

    /// <summary>
    /// Tax Action - provides the info needed to calculate the Tax.
    /// </summary>
    public class TaxAction : IAction
    {
        #region Private Fields

        private DateTime _chargeDate;
        private Currency _actionCurrency;
        private double _rate;
        private double _amount;
        private string _countrySymbol;
        private TaxType _taxOn;

        #endregion

        #region Enums

        public enum TaxType
        {
            DividendTax,
            BuyTax,
            SellTax
        }

        #endregion

        #region C'tors

        /// <summary>
        /// Initializes a new instance of the <see cref="TaxAction"/> class.
        /// </summary>
        /// <param name="currency">The currency.</param>
        /// <param name="chargeDate">The charge date.</param>
        /// <param name="amount">The amount.</param>
        /// <param name="rate">The rate.</param>
        /// <param name="taxOn">The tax on.</param>
        /// <param name="countrySymbol">The country symbol.</param>
        public TaxAction(Currency currency, DateTime chargeDate, double amount,double rate , TaxType taxOn, string countrySymbol)
        {
            _actionCurrency = currency;
            _chargeDate = chargeDate;
            _amount = amount;
            _rate = rate;
            _taxOn = taxOn;
            _countrySymbol = countrySymbol;
        }

        #endregion

        #region Properties

        public DateTime ActionTime
        {
            get { return _chargeDate; }
            set { _chargeDate = value; }
        }

        public double Amount
        {
            get { return _amount; }
            set { _amount = value; }
        }

        public double Rate
        {
            get { return _rate; }
            set { _rate = value; }
        }

        public TaxType TaxOn
        {
            get { return _taxOn; }
            set { _taxOn = value; }
        }

        public string CountrySymbol
        {
            get { return _countrySymbol; }
            set { _countrySymbol = value; }
        }

        public Currency ActionCurrency
        {
            get { return _actionCurrency; }
            set { _actionCurrency = value; }
        }
        #endregion

        #region IAction Members

        public ActionTypes ActionType
        {
            get
            {
                return ActionTypes.Tax;
            }
        }

        #endregion

        #region IComparable<IAction> Members

        int IComparable<IAction>.CompareTo(IAction other)
        {
            if (other == null) return 1;
            if (ActionTime < other.ActionTime) return -1;
            if (ActionTime > other.ActionTime) return 1;
            else return 0;
        }

          #endregion
    }

    /// <summary>
    /// Commission Action - provides the buy info needed to calculate the commission.
    /// </summary>
    public class CommissionAction : IAction
    {
        #region Private Fields

        private DateTime _chargeDate;
        private double _amount;
        private Currency _actionCurrency;
        private double _rate;
        private double _min;
        private double _max;
        private ChargeType _chargeName;
        private double _perStock ;
        private double _periodical ;

        #endregion

        #region Enums

        public enum ChargeType
        {
            BrokerCommission,
            BuyCommission,
            SellCommission
        }

        #endregion

        #region C'tors

        /// <summary>
        /// Initializes a new instance of the <see cref="CommissionAction"/> class.
        /// </summary>
        /// <param name="currency">The currency.</param>
        /// <param name="chargeDate">The charge date.</param>
        /// <param name="amount">The amount.</param>
        /// <param name="chargeName">Name of the charge.</param>
        /// <param name="rate">The rate.</param>
        /// <param name="min">The min.</param>
        /// <param name="max">The max.</param>
        /// <param name="perStock">The per stock.</param>
        /// <param name="periodical">The periodical.</param>
        public CommissionAction(Currency currency, DateTime chargeDate, double amount, ChargeType chargeName, double rate, double min, double max, double perStock, double periodical)
        {
            _actionCurrency = currency;
            _chargeDate = chargeDate;
            _amount = amount;
            _chargeName = chargeName;
            _rate = rate;
            _min = min;
            _max = max;
            _perStock = perStock;
            _periodical = periodical;
        }

        #endregion

        #region Properties

        public DateTime ActionTime
        {
            get { return _chargeDate; }
            set { _chargeDate = value; }
        }

        public double Amount
        {
            get { return _amount; }
            set { _amount = value; }
        }

        public ChargeType ChargeName
        {
            get { return _chargeName; }
            set { _chargeName = value; }
        }

        public Currency ActionCurrency
        {
            get { return _actionCurrency; }
            set { _actionCurrency = value; }
        }
        public double Rate
        {
            get { return _rate; }
            set { _rate = value; }
        }

        public double Min
        {
            get { return _min; }
            set { _min = value; }
        }

        public double Max
        {
            get { return _max; }
            set { _max = value; }
        }

        public double PerStock
        {
            get { return _perStock; }
            set { _perStock = value; }
        }
        public double Periodical
        {
            get { return _periodical; }
            set { _periodical = value; }
        }

        #endregion

        #region IAction Members

        public ActionTypes ActionType
        {
            get
            {
                return ActionTypes.Commission;
            }
        }
        #endregion

        #region IComparable<IAction> Members

        int IComparable<IAction>.CompareTo(IAction other)
        {
            if (other == null) return 1;
            if (ActionTime < other.ActionTime) return -1;
            if (ActionTime > other.ActionTime) return 1;
            else return 0;
        }

        #endregion
    }

    /// <summary>
    /// Managing Fee Action - provides the info needed to calculate the fee.
    /// </summary>
    public class ManagingFeeAction : IAction
    {
        #region Private Fields

        private DateTime _chargeDate;
        private double _amount;
        private Currency _actionCurrency;
        private double _rate;
        private double _min;
        private double _max;
        private double _perStock;
        private double _periodical;

        #endregion

        #region C'tors

        /// <summary>
        /// Initializes a new instance of the <see cref="ManagingFeeAction"/> class.
        /// </summary>
        /// <param name="currency">The currency.</param>
        /// <param name="chargeDate">The charge date.</param>
        /// <param name="amount">The amount.</param>
        /// <param name="rate">The rate.</param>
        /// <param name="min">The min.</param>
        /// <param name="max">The max.</param>
        /// <param name="perStock">The per stock.</param>
        /// <param name="periodical">The periodical.</param>
        public ManagingFeeAction(Currency currency, DateTime chargeDate, double amount, double rate, double min, double max, double perStock, double periodical)
        {
            _actionCurrency = currency;
            _chargeDate = chargeDate;
            _amount = amount;
            _rate = rate;
            _min = min;
            _max = max;
            _perStock = perStock;
            _periodical = periodical;
        }

        #endregion

        #region Properties

        public DateTime ActionTime
        {
            get { return _chargeDate; }
            set { _chargeDate = value; }
        }

        public double Amount
        {
            get { return _amount; }
            set { _amount = value; }
        }

        public Currency ActionCurrency
        {
            get { return _actionCurrency; }
            set { _actionCurrency = value; }
        }
        public double Rate
        {
            get { return _rate; }
            set { _rate = value; }
        }

        public double Min
        {
            get { return _min; }
            set { _min = value; }
        }

        public double Max
        {
            get { return _max; }
            set { _max = value; }
        }

        public double PerStock
        {
            get { return _perStock; }
            set { _perStock = value; }
        }
        public double Periodical
        {
            get { return _periodical; }
            set { _periodical = value; }
        }
        #endregion

        #region IAction Members

        public ActionTypes ActionType
        {
            get
            {
                return ActionTypes.ManagingFee;
            }
        }

        #endregion

        #region IComparable<IAction> Members

        int IComparable<IAction>.CompareTo(IAction other)
        {
            if (other == null) return 1;
            if (ActionTime < other.ActionTime) return -1;
            if (ActionTime > other.ActionTime) return 1;
            else return 0;
        }

          #endregion
    }
}
